#include "build.h"
#include <QProcess>
#include <QString>

#define QD //qDebug() << __FILE__ << __LINE__ << ":"

Build::Build(QObject * parent, QString dirname, QString filename, QString cmdline, SourceType type)
    : QThread(parent)
{
    connect(parent, SIGNAL(stopBuild()), this, SLOT(slotStopBuild()) );
    connect(this, SIGNAL(finished()), this, SLOT(deleteLater()) );

    m_isStopped = false;
    m_targetDirecotry = dirname;
    m_fullName = filename;
    m_cmdline = cmdline;
    m_type = type;

    m_buildProcess = NULL;
    m_errors = 0;
    m_warnings = 0;

    m_stdoutBuf.clear();
    m_stderrBuf.clear();

}

void Build::slotIncErrors() 
{ 
    m_errors++;
}

void Build::slotIncWarnings() 
{ 
    m_warnings++;
}

void Build::run()
{
    qRegisterMetaType<enum QProcess::ExitStatus>("QProcess::ExitStatus");
    QStringList list;

    m_buildProcess = new QProcess();
    connect(m_buildProcess, SIGNAL(finished (int, QProcess::ExitStatus)),
            this, SLOT(slotBuildFinished(int, QProcess::ExitStatus)));
    m_buildProcess->setWorkingDirectory( m_targetDirecotry );

    connect(m_buildProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(slotBuildMessages()) );
    connect(m_buildProcess, SIGNAL(readyReadStandardError()), this, SLOT(slotBuildMessages()) );

    emit message(QString("\n--------" + tr("Start Build")+"--------\n" ));
    m_buildProcess->start(m_cmdline);
    if (!m_buildProcess->waitForStarted(100000)) {
        /* Starting build cmd failed. */
        m_buildProcess->deleteLater();
        emit buildFinished(false);
        return;
    }

    while (!m_buildProcess->waitForFinished(800000)) {
        /* FIXME: Compiler error OR time out?*/
//        m_buildProcess->deleteLater();
        return;
    }
    /* finished */
}

void Build::slotBuildMessages()
{
    QString out = QString::fromLocal8Bit(m_buildProcess->readAllStandardOutput());
    QString err = QString::fromLocal8Bit(m_buildProcess->readAllStandardError());
    if (!out.isEmpty()) {
        m_stdoutBuf += out;
        while (m_stdoutBuf.contains ('\n')) {
            out = m_stdoutBuf.section('\n', 0, 0);
            m_stdoutBuf = m_stdoutBuf.section('\n', 1);
            out += "\n";
            emit message( out, m_targetDirecotry, m_type );
        }
    }
    if (!err.isEmpty()) {
        m_stderrBuf += err;
        while (m_stderrBuf.contains ('\n')) {
            err = m_stderrBuf.section('\n', 0, 0);
            m_stderrBuf = m_stderrBuf.section('\n', 1);
            err += "\n";
            emit message( err, m_targetDirecotry, m_type );
        }
    }
}

void Build::slotStopBuild()
{
    m_isStopped = true;
    emit message( QString("\n--------"+tr("Build stopped")+"--------\n") );
    m_buildProcess->kill();
    m_buildProcess->deleteLater();
}

void Build::slotBuildFinished(int exitcode, QProcess::ExitStatus exitStatus)
{
    emit message( QString::fromLocal8Bit(m_buildProcess->readAllStandardOutput()), m_targetDirecotry, m_type);
    emit message( QString::fromLocal8Bit(m_buildProcess->readAllStandardError()), m_targetDirecotry, m_type);
    m_buildProcess->deleteLater();
    if (exitStatus == QProcess::NormalExit && exitcode == 0)
        emit buildFinished(true);
    else
        emit buildFinished(false);
}
